package com.itheima.health.controller;

import com.itheima.health.common.MessageConst;
import com.itheima.health.entity.Result;
import com.itheima.health.service.MemberService;
import com.itheima.health.service.OrderService;
import com.itheima.health.service.ReportService;
import com.itheima.health.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

import static org.apache.commons.lang3.time.DateFormatUtils.format;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: lenovo
 * @Date: 17:02 2021/4/23
 */
@RestController
@RequestMapping("report")
@Slf4j
public class ReportController {

    @DubboReference
    private MemberService memberService;
    @DubboReference
    private ReportService reportService;
    @DubboReference
    private OrderService orderService;

    /**
     * @Author: lenovo
     * @Parms []
     * @ReturnType: com.huai.health_common.entity.Result
     * @Description: 会员查询默认页面数据
     */
    @GetMapping("getMemberReport")
    public Result getMemberReport() {
        Map<String, Object> resultMap = new HashMap<>();
        //组装最近12个月的日期数据
        List<String> months = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -13);
        for (int i = 0; i < 12; i++) {
            calendar.add(Calendar.MONTH, 1);
            String format = sdf.format(calendar.getTime());
            months.add(format);
        }
        resultMap.put("months", months);
        //查询最近12个月的会员统计数据
        List<Integer> memberCount = reportService.getMemberReport(months);
        resultMap.put("memberCount", memberCount);
        return new Result(true, MessageConst.ACTION_SUCCESS, resultMap);
    }
//    start=${yyMMdd(date01)}&end=${yyMMdd(date02)}

    /**
     * @Author: lenovo
     * @Parms [start, end]
     * @ReturnType: com.huai.health_common.entity.Result
     * @Description: 通过日历空间查询到的会员数据
     */
    @RequestMapping("/getMemberReportBetween")
    public Result getMemberReport(String start, String end) {
        List<String> months;
        List<Integer> memberCount;
        months = getMonthBetweenDates(start, end);

        memberCount = memberService.countByMonth(months);

        Map<String, Object> map = new HashMap<>();
        map.put("months", months);
        map.put("memberCount", memberCount);

        log.info("[会员统计-]data{},{}", months, memberCount);
        return new Result(true, MessageConst.GET_MEMBER_NUMBER_REPORT_SUCCESS, map);
    }

    /**
     * @Author: lenovo
     * @Parms [minDate, maxDate]
     * @ReturnType: java.util.List<java.lang.String>
     * @Description: 两个月份之间的时间
     */
    public static List<String> getMonthBetweenDates(String minDate, String maxDate) {
        ArrayList<String> result = new ArrayList<>();
        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();
        min.setTime(DateUtils.parseToDate(minDate, "yyyy-MM"));
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
        max.setTime(DateUtils.parseToDate(maxDate, "yyyy-MM"));
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            result.add(format(curr.getTime(), "yyyy-MM"));
            curr.add(Calendar.MONTH, 1);
        }
        return result;
    }


    @GetMapping("getSetmealReport")
    public Result getSetmealReport() {
        List<Map<String, Object>> setmealCount = reportService.getSetmealReport();
        List<String> setmealNames = new ArrayList<>();
        for (Map<String, Object> map : setmealCount) {
            String name = (String) map.get("name");
            setmealNames.add(name);
        }
        Map<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("setmealCount", setmealCount);
        objectObjectHashMap.put("setmealNames", setmealNames);
        return new Result(true, "成功", objectObjectHashMap);
    }

    @GetMapping("getBusinessReportData")
    public Result getBusinessReportData() {
        Map<String, Object> resultMap = reportService.getBusinessReportData();
        return new Result(true, MessageConst.GET_BUSINESS_REPORT_SUCCESS, resultMap);
    }

    /**
     * @Author: lenovo
     * @Date: 9:00 2021/3/10
     * @Parms []
     * @ReturnType: com.huai.health_common.entity.Result
     * @Description: 通过性别查询套餐
     */
    @RequestMapping("/getMemberBySexReport")
    public Result getSetmealBySexReport() {
        List<Map<String, Object>> setmealCount = memberService.countBySex();
        List<String> setmealNames = new ArrayList<>();
        for (Map<String, Object> elem : setmealCount) {
            setmealNames.add((String) elem.get("name"));
           /* if (elem.get("sex")==null){
                setmealNames.add("未填写");
            }else {
//                setmealNames.add(String.valueOf((Integer.parseInt((String) elem.get("sex"))==1)?'男':'女'));
            }*/
        }

        Map<String, Object> map = new HashMap<>();
        map.put("setmealNames", setmealNames);
        map.put("setmealCount", setmealCount);
        log.info("会员性别占比饼状图数据：data{},{}", setmealNames, setmealCount);
        return new Result(true, MessageConst.GET_SETMEAL_COUNT_REPORT_SUCCESS, map);
    }

    /**
     * @Author: lenovo
     * @Date: 14:57 2021/3/11
     * @Parms []
     * @ReturnType: com.huai.health_common.entity.Result
     * @Description: 根据会员各年龄段查询
     */
    @RequestMapping("/getMemberByAgeRange")
    public Result getMemberByAgeRange() {
        List<Map<String, Object>> memberAgeCount = memberService.countByAgeRange();
        List<String> memberAgeCountNams = new ArrayList<>();
        for (Map<String, Object> elem : memberAgeCount) {
            memberAgeCountNams.add((String) elem.get("name"));
        }

        Map<String, Object> map = new HashMap<>();
        map.put("memberAgeCountNams", memberAgeCountNams);
        map.put("memberAgeCount", memberAgeCount);
        log.info("会员性别占比饼状图数据：data{},{}", memberAgeCountNams, memberAgeCount);
        return new Result(true, MessageConst.GET_SETMEAL_COUNT_REPORT_SUCCESS, map);
    }

    /**
     * @Author: lenovo
     * @Parms [response]
     * @ReturnType: com.itheima.health.entity.Result
     * @Description: 导出统计表
     */

    /**
     * 导出运营数据表格
     * @param response
     * @throws IOException
     */
   @RequestMapping("/exportBusinessReport")
    public Result exportBusinessReport(HttpServletResponse response) {
        log.info("[导出运营数据表-开始]");

//        rpc调用
        Map<String, Object> reportData = reportService.getBusinessReportData();
        log.info("[导出运营数据表]data{}", reportData);

        String reportDate = (String) reportData.get("reportDate");
        // 获取会员相关数据
        long todayNewMember = Long.parseLong(reportData.get("todayNewMember").toString());
        long thisWeekNewMember = Long.parseLong(reportData.get("thisWeekNewMember").toString());
        long thisMonthNewMember = Long.parseLong(reportData.get("thisMonthNewMember").toString());
        long totalMember = Long.parseLong(reportData.get("totalMember").toString());
        // 获取预约相关数据
        long todayOrderNumber = Long.parseLong(reportData.get("todayOrderNumber").toString());
        long thisWeekOrderNumber = Long.parseLong(reportData.get("thisWeekOrderNumber").toString());
        long thisMonthOrderNumber = Long.parseLong(reportData.get("thisMonthOrderNumber").toString());
        // 获取到诊相关数据
        long todayVisitsNumber = Long.parseLong(reportData.get("todayVisitsNumber").toString());
        long thisWeekVisitsNumber = Long.parseLong(reportData.get("thisWeekVisitsNumber").toString());
        long thisMonthVisitsNumber = Long.parseLong(reportData.get("thisMonthVisitsNumber").toString());
        // 获取套餐数据
        List<Map> hotSetmeal = (List<Map>) reportData.get("hotSetmeal");

        try {
            InputStream in = this.getClass().getClassLoader().getResourceAsStream("report_template.xlsx");
            assert in != null;
            Workbook workbook = new XSSFWorkbook(in);
            OutputStream stream = response.getOutputStream();
            Sheet sheet = workbook.getSheetAt(0);
//            向空表中填入数据
            //日期
            sheet.getRow(2).getCell(5).setCellValue(reportDate);
            //会员统计数据
            sheet.getRow(4).getCell(5).setCellValue(todayNewMember);
            sheet.getRow(4).getCell(7).setCellValue(totalMember);
            sheet.getRow(5).getCell(5).setCellValue(thisWeekNewMember);
            sheet.getRow(5).getCell(7).setCellValue(thisMonthNewMember);
            //预约到诊数据统计
            sheet.getRow(7).getCell(5).setCellValue(todayOrderNumber);
            sheet.getRow(7).getCell(7).setCellValue(todayVisitsNumber);
            sheet.getRow(8).getCell(5).setCellValue(thisWeekOrderNumber);
            sheet.getRow(8).getCell(7).setCellValue(thisWeekVisitsNumber);
            sheet.getRow(9).getCell(5).setCellValue(thisMonthOrderNumber);
            sheet.getRow(9).getCell(7).setCellValue(thisMonthVisitsNumber);
//            设置热门套餐
            int rowNum = 12;
            for (Map map : hotSetmeal) {
                Row row = sheet.getRow(rowNum);
                row.getCell(4).setCellValue((String) map.get("name"));
                row.getCell(5).setCellValue((Long) map.get("setmeal_count"));
                row.getCell(6).setCellValue(((BigDecimal) map.get("proportion")).doubleValue());
                rowNum++;
            }
//            写入网络输出流
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("content-Disposition", "attachment;fileName=" + reportDate + "_report.xlsx");
            workbook.write(stream);
            return new Result(true, MessageConst.ACTION_SUCCESS, reportData);
        } catch (IOException e) {
            log.error("", e);
            return new Result(false, MessageConst.ACTION_FAIL);
        }
    }
}
